package sg.nus.iss.vmcs.controllers;

import sg.nus.iss.vmcs.models.Coin;


/**
 * Abstract Coin Handler that validates an input coin's weight against a standard coin <br><br>
 * Modifications:
 * 1/1/2011 - Philip - Refactored Class 
 * @author Raj
 * @author Philip
 */
public abstract class CoinHandler 
{
	/** Reference to a standard coin */
	protected Coin stdCoin;
	
	/** Reference to the succesor that does processing if this handler does not handle */
	private CoinHandler successor;
	
	/**
	 * Abstract Constructor. Assigns the standard coin that is used for comparison
	 * @param stdCoin
	 */
	public CoinHandler(Coin stdCoin) {
		this.stdCoin = stdCoin;
	}

	/**
	 * Sets the successor to this handler
	 * @param successor the successor to set
	 */
	public void setSuccessor(CoinHandler successor) {
		this.successor = successor;
	}
	
	/**
	 * This method has to be implemented by each CoinHandler and 
	 * set the value of the incoming Coin object if its weight
	 * is same as that of the expected coin by the specific handler
	 * 
	 * If the coin is not handled by any of the handlers, the coin object will have <u>null</u> <b>value</b> 
	 * 
	 * Returns true if the coin matches the weight of the expected coin from the CashStoreItem
	 * For example, if it is a FiveCentCoinHandler then the input coin's weight should match 
	 * with that of the FiveCentCoin from the CashStoreItem
	 *  
	 * @param coin
	 * @return
	 */
	protected abstract boolean validateCoin(double weight);
	
	/**
	 * Handles the Input Coin and passes on the control to next Handler (if any)
	 * @param coinInput
	 */
	public final Coin handleCoin(double weight)
	{
		if(this.validateCoin(weight)) {
			System.out.println(stdCoin.getName() + "Handler has handled the coin");
			return stdCoin;
		}
		else if(successor != null) {
			System.out.println(stdCoin.getName() + "Handler cannot handle the coin");
			return successor.handleCoin(weight);
		}
		else {
			System.out.println(stdCoin.getName() + "Handler cannot handle the coin");
			System.out.println("Invalid coin inserted");
			return null;
		}
	}
}
